// ani-slider/index.js
Component({
	options: {
    multipleSlots: true // 在组件定义时的选项中启用多slot支持
  },
	/**
	 * 组件的属性列表
	 */
	properties: {
		// 组件长度
		width:{
			value:320,
			type:Number
		},
		// 焦点值
		sliderValue:{
			value:{
				min:0,
				max:100
			},
			type:Object
		},
		// 最小值
		min:{
			value:0,
			type:Number
		},
		// 最大值
		max:{
			value:100,
			type:Number
		},
		// 步长
		step:{
			value:1,
			type:Number
    },
    toStep:{
      value:false,
			type:Boolean
    },
		// 是否禁用
		disabled:{
			value:false,
			type:Boolean
		},
		// block颜色
		blockColor:{
			value:'#FFFFFF',
			type:String
		},
		// 区间线颜色
		activeColor:{
			valur:'#000000',
			type:String
		},
		// 线颜色
		backgroundColor:{
			value:'#D4D4D4',
			type:String
		},
		// block大小
		blockSize:{
			value:26,
			type:Number
		}
	},

	/**
	 * 组件的初始数据
	 */
	data: {
		positionValue:{
			left:0,
			right:100
		},
	},
	observers:{
		"width,sliderValue,min,max,step,sliderValue.min,sliderValue.max"(){
			this.checkValue()
			this.value2position()
		}
	},
	ready(){
		setTimeout(_=>{
			this.initSlider()
		},1000)
	},
	methods: {
		initSlider() {
			this.checkValue()
			// 获取容器位置
			const query = wx.createSelectorQuery().in(this)
			query.select('#sliderWarp').boundingClientRect()
			query.exec((res)=>{
				this.setData({viewInfo:res[0]})
			})
			this.value2position()
			let {min,max,sliderValue:{min:minVal,max:maxVal}}=this.data
			if(min==minVal&&maxVal==minVal){
				this.setData({
					sliderTap:'right'
				})
			}
			if(max==maxVal&&maxVal==minVal){
				this.setData({
					sliderTap:'left'
				})
			}
		// setInterval(_=>{
    //   console.error(this.data)
    // },1000)
		},
		// 检查数值合法性
		checkValue(){
			const {min,max,step,sliderValue:{min:minVal,max:maxVal},blockSize}=this.data
			const a=(max-min)/step
			if(step>max){
				console.warn('步长必须小于最大值')
			}
			// console.log(this.data)
			// if(step>min){
			// 	throw new Error('步长必须小于最小值')
			// }
			if(a*step!=(max-min)){
				console.warn('步长必须可以被(max - min)整除')
			}
			// if(minVal>max||minVal<min||maxVal>max||maxVal<min||max<min){
			// 	throw new Error('数值设定不合理 请重新设置')
			// }
			if(blockSize>32){
				console.warn('block设置最大值为32')
				this.setData({blockSize:32})
			}
			if(blockSize<12){
				console.warn('block设置最小值为12')
				this.setData({blockSize:12})
			}
			if(step>=10){
				let stepArr=(step+'').split('').reverse().findIndex(x=>x!=0);
				if(stepArr>0){
					let str='1'
					for(let i=0;i<stepArr;i++){
						str+='0'
					}
					this.setData({stepNum:str*1})
				}
			}
			// step最小区间100份
			// if(step/(max-min)<0.01){
			// 	this.data.step=(max-min)/100
			// }
		},
		// 外部数值的步长转换
		setStep(val){
			const step=this.data.step
			let stepVal=accMul(parseFloat((val/step).toFixed(1)),step)
			const stepNum=this.data.stepNum
			if(stepNum){
				stepVal=parseInt(stepVal/stepNum)*stepNum
			}else if(step<10&&step>=1){
				stepVal=parseInt(stepVal)
			}
			return stepVal
		},
		// 将slider内部坐标转换为外部数值
		position2value(haveStep=false){
			const {min,max,positionValue:{left,right}}=this.data
			const section=max-min;
			const minVal=left*section/100;
			const maxVal=right*section/100;
			const minSection=this.setStep(min+minVal)
      const maxSection=this.setStep(min+maxVal)
    
			this.setData({
				sliderValue:{
					min:haveStep?minSection:(min+minVal),
					max:haveStep?maxSection:(min+maxVal)
        },
        sliderWarpValue:{
					min:minSection,
					max:maxSection
        },
			})
			// this.setData({
			// 	sliderValue:{
			// 		min:accAdd(min,minSection),
			// 		max:accAdd(min,maxSection)
			// 	}
			// })
			// this.setStep()
			return {min:minVal,max:maxVal}
		},
		// 将外部数值转换为内部坐标  多用于 数值在外部带入时候调用
		value2position(){
			const {min,max,step,sliderValue:{min:minVal,max:maxVal}}=this.data
			const section=max-min
			const left=(minVal-min)/section*100
			const right=(maxVal-min)/section*100
			this.setData({
				positionValue:{
					left,
					right
				}
			})
		},
		sliderStart(e){
			const {type}=e.currentTarget.dataset;
			this.setData({sliderTap:type})
		},
		sliderEnd(){
      if(this.data.disabled) return

      this.position2value(true)
			this.triggerEvent('changeend',{...this.data.sliderChangeNew,position:this.data.positionValue})
		},
		sliderMove(e){
			if(this.data.disabled) return
			const {type}=e.currentTarget.dataset
			const {clientX}=e.changedTouches[0]
			const {left:viewLeft,width:viewWidth}=this.data.viewInfo
			const position=this.checkPosition(clientX-viewLeft,type)
			const percentPosition=position/viewWidth*100;
			const valueStr=`positionValue.${type}`
			this.setData({
				[valueStr]:percentPosition
      })
      // console.log(percentPosition)
			// 坐标转换为外部数值
      this.position2value()
			this.triggerEvent('change',{...this.data.sliderWarpValue,position:this.data.positionValue})
		},
		checkPosition(position,type){
			const {width:viewWidth}=this.data.viewInfo
			const {left,right}=this.data.positionValue
			const percentPosition=position/viewWidth*100;
			if(type==='left'&&percentPosition>right){
				return this.percent2left(right)
			}else if(type==='right'&&percentPosition<left){
				return this.percent2left(left)
			}
			if(percentPosition<0){
				return 0
			}else if(percentPosition>100){
				return viewWidth
			}
			return position
		},
		percent2left(percent){
			return percent/100*this.data.viewInfo.width
		},
		left2percent(left){
			return left/this.data.viewInfo.width*100
		}
	}
})

function accMul(arg1, arg2) {
	var m = 0,
		s1 = arg1.toString(),
		s2 = arg2.toString();
	try {
		m += s1.split(".")[1].length
	} catch (e) {}
	try {
		m += s2.split(".")[1].length
	} catch (e) {}
	return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m)
}

function accAdd(arg1, arg2) {
	var r1, r2, m;
	try {
		r1 = arg1.toString().split(".")[1].length
	} catch (e) {
		r1 = 0
	}
	try {
		r2 = arg2.toString().split(".")[1].length
	} catch (e) {
		r2 = 0
	}
	m = Math.pow(10, Math.max(r1, r2))
	return (arg1 * m + arg2 * m) / m
}